package com.umeox.watch.moto.dataservice.observer;

import android.content.Context;
import android.os.Build;
import android.telephony.CellInfo;
import android.telephony.CellInfoCdma;
import android.telephony.CellInfoGsm;
import android.telephony.CellInfoLte;
import android.telephony.CellInfoWcdma;
import android.telephony.CellLocation;
import android.telephony.PhoneStateListener;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.telephony.cdma.CdmaCellLocation;
import android.telephony.gsm.GsmCellLocation;

import com.umeox.moto.common.log.Logger;
import com.umeox.moto.common.utils.AndroidUtils;
import com.umeox.moto.common.utils.StringUtils;
import com.umeox.watch.moto.dataservice.base.BaseApp;
import com.umeox.watch.moto.dataservice.utils.Utils;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicBoolean;

public class CellInfoObserver extends PhoneStateListener {

    private static volatile CellInfoObserver instance;

    private final String cellTowerFormat = "%1$s#%2$s#%3$s#%4$s#%5$s";
    private final List<String> nearByCellTowers = new ArrayList<>();
    private final AtomicBoolean registed = new AtomicBoolean();
    private String mcc, mnc, cid, lac, signal;

    private CellInfoObserver() {
        Logger.i("初始化CellInfoObserver");
    }

    public static CellInfoObserver getInstance() {
        if (instance == null) {
            synchronized (CellInfoObserver.class) {
                if (instance == null) {
                    instance = new CellInfoObserver();
                }
            }
        }
        return instance;
    }

    public String getSignal(){
        return signal;
    }

    public String getMcc() {
        if (StringUtils.isEmpty(mcc)
                || Integer.toHexString(-1).equals(mcc)) {
            mcc = String.valueOf(AndroidUtils.getMCC());
        }
        return mcc;
    }

    public String getMnc() {
        if (StringUtils.isEmpty(mnc)
                || Integer.toHexString(-1).equals(mnc)) {
            mnc = String.valueOf(AndroidUtils.getMNC());
        }
        return mnc;
    }

    public void registerObserver() {
        Logger.i("注册Observer");
        if (registed.compareAndSet(false, true)) {
            TelephonyManager telephonyManager = (TelephonyManager) BaseApp.getInstance().getSystemService(Context.TELEPHONY_SERVICE);
            telephonyManager.listen(CellInfoObserver.this,
                    PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
                            | PhoneStateListener.LISTEN_CELL_LOCATION
                            | PhoneStateListener.LISTEN_CELL_INFO);
        }
    }

    public String getCurrentCellTower() {
        Logger.e("cid=" + cid + ",lac=" + lac);
        if (!StringUtils.isEmpty(cid) && Integer.parseInt(cid) > -1 && !StringUtils.isEmpty(lac) && Integer.parseInt(lac) > -1) {
            return String.format(Locale.ENGLISH, cellTowerFormat, getMcc(), getMnc(), cid, lac, signal);
        } else {
            return Utils.getCurrentCellTower(BaseApp.getInstance());
        }
    }

    public List<String> getNearByCellTowers() {
        if (nearByCellTowers == null
                || nearByCellTowers.isEmpty()) {
            return Utils.getNearByCellTowers(BaseApp.getInstance());
        } else {
            return nearByCellTowers;
        }
    }

    @Override
    public void onSignalStrengthsChanged(SignalStrength signalStrength) {
        signal = String.valueOf(Utils.getSignalStrengthDbm(signalStrength));
    }

    @Override
    public void onCellLocationChanged(CellLocation currentCellInfo) {
        Logger.i("onCellLocationChanged->" + currentCellInfo);
        try {
            // GSM网
            if (currentCellInfo instanceof GsmCellLocation) {
                GsmCellLocation gsm = (GsmCellLocation) currentCellInfo;
                lac = String.valueOf(gsm.getLac());
                cid = String.valueOf(gsm.getCid());
            }
            // 电信cdma网
            else if (currentCellInfo instanceof CdmaCellLocation) {
                CdmaCellLocation cdma = (CdmaCellLocation) currentCellInfo;
                lac = String.valueOf(cdma.getNetworkId());
                cid = String.valueOf(cdma.getBaseStationId());
                Logger.e("onCellLocationChanged cid=" + cid + ",lac=" + lac);
            } else {
                Logger.i("CellLocation is null!!!");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onCellInfoChanged(List<CellInfo> cellInfos) {
        if (cellInfos != null && !cellInfos.isEmpty()) {
            nearByCellTowers.clear();
            for (CellInfo cellInfo : cellInfos) {
                String cellTower = "";
                if (cellInfo instanceof CellInfoGsm) {
                    CellInfoGsm cellInfoGsm = (CellInfoGsm) cellInfo;
                    cellTower = String.format(Locale.ENGLISH,
                            cellTowerFormat,
                            getMcc(),
                            getMnc(),
                            cellInfoGsm.getCellIdentity().getCid(),
                            cellInfoGsm.getCellIdentity().getLac(),
                            cellInfoGsm.getCellSignalStrength().getDbm());
                } else if (cellInfo instanceof CellInfoCdma) {
                    CellInfoCdma cellInfoCdma = (CellInfoCdma) cellInfo;
                    cellTower = String.format(Locale.ENGLISH,
                            cellTowerFormat,
                            getMcc(),
                            getMnc(),
                            cellInfoCdma.getCellIdentity().getBasestationId(),
                            cellInfoCdma.getCellIdentity().getNetworkId(),
                            cellInfoCdma.getCellSignalStrength().getDbm());
                } else if (cellInfo instanceof CellInfoLte) {
                    CellInfoLte cellInfoLte = (CellInfoLte) cellInfo;
                    cellTower = String.format(Locale.ENGLISH,
                            cellTowerFormat,
                            cellInfoLte.getCellIdentity().getMcc(),
                            cellInfoLte.getCellIdentity().getMnc(),
                            cellInfoLte.getCellIdentity().getCi(),
                            cellInfoLte.getCellIdentity().getTac(),
                            cellInfoLte.getCellSignalStrength().getDbm());
                } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
                    if (cellInfo instanceof CellInfoWcdma) {
                        CellInfoWcdma cellInfoWcdma = (CellInfoWcdma) cellInfo;
                        cellTower = String.format(Locale.ENGLISH,
                                cellTowerFormat,
                                cellInfoWcdma.getCellIdentity().getMcc(),
                                cellInfoWcdma.getCellIdentity().getMnc(),
                                cellInfoWcdma.getCellIdentity().getCid(),
                                cellInfoWcdma.getCellIdentity().getLac(),
                                cellInfoWcdma.getCellSignalStrength().getDbm());
                    }
                }

                if (!StringUtils.isEmpty(cellTower)) {
                    if (cellInfo.isRegistered()) {
                        nearByCellTowers.add(0, cellTower);
                    } else {
                        nearByCellTowers.add(cellTower);
                    }
                }
            }
        }
        Logger.i("onCellInfoChanged->" + nearByCellTowers);
    }
}
